﻿#include "../Misc.h"
#include "bMath.h"
#include <iomanip>
#include <random>

namespace Base {

	static std::random_device s_rd;
	static std::mt19937 s_gen(s_rd());

	// return [min,max) 之间的一个
	int RandomInt(int min, int max) {
		D_ASSERT(min <= max, "min should <= max");
		std::uniform_int_distribution distrib(min, max - 1);
		return distrib(s_gen);
	}

	// return [0,1]之间的一个随机浮点数
	float Random01() {
		std::uniform_real_distribution<float> distrib(0, 1.0f);
		return distrib(s_gen);
	}

	// return [min,max] 之间一个随机浮点数
	float RandomFloat(float min, float max) {
		D_ASSERT(min <= max, "min should <= max");
		std::uniform_real_distribution distrib(min, max);
		return static_cast<float>(distrib(s_gen));
	}

	//-----------------------------------------------
	// 全局方法
	Vec4 operator*(const Vec4& lhs, const Matrix4x4& rhs) {
		Vec4 v;
		XMStoreFloat4(&v.data, XMVector4Transform(XMLoadFloat4(&lhs.data), XMLoadFloat4x4(&rhs.data)));
		return v;
	}


	std::ostream& operator<<(std::ostream& os, const Vec2& v2) {
		os << "< " << v2.x << ", " << v2.y << " >" << std::endl;
		return os;
	}
	std::ostream& operator<<(std::ostream& os, const Vec3& v3) {
		os << "< " << v3.x << ", " << v3.y << ", " << v3.z << " >" << std::endl;
		return os;
	}
	std::ostream& operator<<(std::ostream& os, const Vec4& v4) {
		os << "< " << v4.x << ", " << v4.y << ", " << v4.z << ", " << v4.w << " >" << std::endl;
		return os;
	}
	std::ostream& operator<<(std::ostream& os, const Quaternion& q) {
		os << "< " << q.x << ", " << q.y << ", " << q.z << ", " << q.w << " >" << std::endl;
		return os;
	}
	std::ostream& operator<<(std::ostream& os, const Matrix4x4& mat4x4) {
		os << "[ " << mat4x4(0, 0) << ", " << mat4x4(0, 1) << ", " << mat4x4(0, 2) << ", " << mat4x4(0, 3) << " ]" << '\n';
		os << "[ " << mat4x4(1, 0) << ", " << mat4x4(1, 1) << ", " << mat4x4(1, 2) << ", " << mat4x4(1, 3) << " ]" << '\n';
		os << "[ " << mat4x4(2, 0) << ", " << mat4x4(2, 1) << ", " << mat4x4(2, 2) << ", " << mat4x4(2, 3) << " ]" << '\n';
		os << "[ " << mat4x4(3, 0) << ", " << mat4x4(3, 1) << ", " << mat4x4(3, 2) << ", " << mat4x4(3, 3) << " ]" << std::endl;
		return os;
	}

	//-------------------------------------------
	// 各种数据类型转换
	Matrix4x4 QuaternionToMatrix4x4(const Quaternion& q) {
		Matrix4x4 result;
		XMStoreFloat4x4(&result.data, XMMatrixRotationQuaternion(XMLoadFloat4(&q.data)));
		return result;
	}

	Quaternion Matrix4x4ToQuaternion(const Matrix4x4& matrix) {
		Quaternion result;
		XMStoreFloat4(&result.data, XMQuaternionRotationMatrix(XMLoadFloat4x4(&matrix.data)));
		return result;
	}


	Vec3 SphereToDecare(float r, float thetaRad, float phiRad) {
		Vec3 pos;
		pos.z = r * cosf(thetaRad);
		pos.x = r * sinf(thetaRad) * cosf(phiRad);
		pos.y = r * sinf(thetaRad) * sinf(phiRad);
		return pos;
	}
}